Communitytreffen-Moderator
Zitat von Mivey
Könnt man nicht gleich alles statisch linken also ohne Container, so dass das Program gar nicht suchen muss was auf dem lokalen System installiert ist? Wäre den doch auch "reproduzierbar" und würd auch nicht mehr Speicher brauchen als x-Schichten von virtuellen System.
...
Jein... es gibt da noch ein paar mehr Aspekte, warum Container praktisch sind:
- Das Konzept funktioniert auch für Szenarien, wo statisches Linken nicht möglich ist (z.B. wenn eine eigenständige Executable aufgerufen wird oder in interpretierten Sprachen, die nicht alles dynamisch linken können)
- Container haben einen enormen Sicherheitsvorteil. Alles, was nicht explizit freigegeben wird, ist für den Container unsichtbar. Das heißt, selbst wenn ein Angreifer Rootrechte im Container kriegt, kann er damit kaum Schaden anrichten. Er kann im Wesentlichen nur auf die Daten zugreifen, die zu diesem einen Prozess gehören.
- Wenn in einem Container tatsächlich mal Dateien beschädigt werden (durch einen Bug oder weil ein Angreifer ausführbaren Code durch Malware ersetzt), lässt sich der Container sehr einfach wegwerfen und neu initialisieren (z.B. docker-compose stop && docker-compose rm -f && docker-compse up -d)
- Wenn ich auf einem Server neue Software installieren will, muss ich mir gar keine Gedanken machen, welche Abhängigkeiten ich installieren muss, selbst wenn die Software nicht in meinem Paketmanager ist (was für viele Webanwendungen gilt). Mit einer 20 Zeilen langen docker-compose.yml bekomme ich eine Owncloud Instanz mit allem, was dazu gehört. Oder Feedbin. Oder Piwik. Oder einen Minecraft Server...
- Ich kann mir sicher sein, dass auf meiner Entwicklermaschine exakt die gleichen Versionen von allem laufen, wie auf dem Server. Auch noch in einem Jahr, wenn ich einen Bug in einer alten Version reproduzieren muss.
Viele dieser Vorteile hätten einzelne VMs pro Anwendung natürlich auch, aber die brauchen mehr Platz auf der Festplatte, mehr RAM, mehr CPU und mehr Zeit zum Booten, weil sie jeweils einen eigenen Kernel und eigene Treiber mitbringen. Ein Docker Container startet genau so schnell, wie ein blanker Prozess und hat einen vernachlässigbaren Performanceoverhead. Der Platzbedarf auf der Festplatte ist zwar etwas höher, als bei einer Direktinstallation, aber immer noch deutlich unter dem von einer ganzen VM. Zumal Docker auf einem Dateisystem aufbaut, das in Schichten organisiert ist. Wenn ich zwei Container habe, die auf dem gleichen Image aufbauen, liegt das Image auch nur einmal auf der Platte, pro Container werden nur die jeweils veränderten Dateien neu abgelegt. Die Images in sich sind auch nochmal geschichtet, Wenn ich z.B. zwei Rails Anwendungen habe, können die beide vom Basisimage ruby:2.3 erben und die Images ruby:2.3 und node:6.3 basieren (momentan) beide auf dem gleichen Basisimage buildpack-deps:jessie. Außerdem sind die Basisimages in der Regel so sehr abgespeckt, dass wirklich nur das drin ist, was man braucht. In den oben genannten hat man z.B. nicht mal less oder einen einfachen Texteditor.
Container in einer VM sind natürlich ziemlich unhandlich. Das liegt aber aus den oben genannten Gründen mehr an der VM, als an den Containern. Und zumindest unter Windows könnte das Problem demnächst wegfallen, da der Windows Kernel seit dem aktuellen Update auch Linux Binaries ausführen kann (yay!). Docker funktioniert zwar noch nicht richtig, aber so wies aussieht, dürfte das bald behoben sein.
Disclaimer: ich betreibe einen Ubuntu 16.04 Server, auf dem aktuell 19 Docker-Container (z.B. vier davon für die BMT-Website) laufen.